<?php
/**
 * Date: 2024.8
 * Author: kahn
 */

namespace service\vip\payment;

use AliPay\App;
use AliPay\Trade;
use AliPay\Wap;
use AliPay\Web;
use config\Payment;
use config\Order;
use WeChat\Exceptions\InvalidResponseException;
use WeChat\Exceptions\LocalCacheException;

class AlipayService extends \Service{

    /**
     * @param $price
     * @param $sn
     * @param $dsc
     * @return array|null
     */
    public function payApp($price, $sn, $dsc): ?array
    {
        $pay = App::instance(Payment::ALIPAY);
        $res = $pay->apply([
            'subject'=>$dsc,
            'out_trade_no'=>$sn,
            'total_amount'=>$price,
            'notify_url'   => \Yaf_Registry::get("config")->server->url . Payment::ALIPAY['notify_uri'],
        ]);

        if(!$res){
            return null;
        }

        return ['orderStr' => $res];
    }

    /**
     * @param $price
     * @param $sn
     * @param $dsc
     * @return array|null
     */
    public function payWeb($price, $sn, $dsc): ?array
    {
        $pay = Web::instance(Payment::ALIPAY);
        $res = $pay->apply([
            'subject'=>$dsc,
            'out_trade_no'=>$sn,
            'total_amount'=>$price,
            'notify_url'   => \Yaf_Registry::get("config")->server->url . Payment::ALIPAY['notify_uri'],
        ]);
        if(!$res){
            return null;
        }
        return ['pageRedirectionData' => $res];

    }

    /**
     * @param $price
     * @param $sn
     * @param $dsc
     * @return array|null
     */
    public function payWap($price, $sn, $dsc): ?array
    {
        $pay = Wap::instance(Payment::ALIPAY);
        $res = $pay->apply([
            'subject'=>$dsc,
            'out_trade_no'=>$sn,
            'total_amount'=>$price,
            'notify_url'   => \Yaf_Registry::get("config")->server->url . Payment::ALIPAY['notify_uri'],
        ]);

        if(!$res){
            return null;
        }
        return ['pageRedirectionData' => $res];
    }

    /**
     * 支付接口（自动根据参数决定是app还是web端支付）
     * @param $product
     * @param $price
     * @param $sn
     * @param $desc
     * @return array|null
     */
    public function pay($payWay, $price, $sn, $desc): ?array
    {
        $res = null;
        switch ($payWay){
            case Order::PAY_WAY_APP:
                $res = $this->payApp($price, $sn, $desc);
                break;
            case Order::PAY_WAY_WEB:
                $res = $this->payWeb($price, $sn, $desc);
                break;
            case Order::PAY_WAY_WAP:
                $res = $this->payWap($price, $sn, $desc);
                break;
        }

        return $res;
    }

    /**
     * @throws InvalidResponseException
     * @throws LocalCacheException
     */
    public function query($out_trade_no): ?array
    {
        $pay = Trade::instance(Payment::ALIPAY);
        $res = $pay->query($out_trade_no);
        $res = json_decode($res,true);
        if(!$res){
            return null;
        }
        $data = $res['alipay_trade_query_response'];
        if ($data['code'] == '10000'){
            if ($data['trade_status'] == 'TRADE_SUCCESS' || $data['trade_status'] == 'TRADE_FINISHED'){
                $sn = $data['out_trade_no'];
                $price = $data['total_amount'];
                $tradeno = $data['trade_no']; //订单号
                $paidTime = strtotime($data['gmt_payment']);

                return [$sn, $price, $tradeno, $paidTime];
            }else{
                return null;
            }
        }else{
            return null;
        }
    }

    /**
     * @return array|null
     */
    public function notify(): ?array
    {
        try {
            $pay = Trade::instance(Payment::ALIPAY);
            $data = $pay->notify();
            \Log::info('alipay notify ', $data);

            if ($data['trade_status'] == 'TRADE_SUCCESS' || $data['trade_status'] == 'TRADE_FINISHED') {
                $sn = $data['out_trade_no'];
                $price = $data['total_amount'];
                $tradeno = $data['trade_no']; //订单号
                $paidTime = strtotime($data['gmt_payment']);

                return [$sn, $price, $tradeno, $paidTime];
            } else {
                \Log::error("alipay notify error, status error ", $data);
                return null;
            }
        } catch (\Exception $e) {
            // 异常处理
            \Log::error("alipay notify error, verify error ", $e->getMessage());
            return null;
        }
    }
}